home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 6: Level 6
/
17 Bit - Level 6 (1998)(Epic Marketing)[!].iso
/
!applications!
/
crmv1.91t
/
developer
/
assembler
/
examples
/
crmdata.s
< prev
next >
Wrap
Text File
|
1993-02-03
|
16KB
|
775 lines
*********************************
*** CrMData V1.01 ***
*** (c) 1993 Thomas Schwarz ***
*********************************
incdir dh0:ass/Include/
include exec/exec_lib.i
include dos/dos_lib.i
include dos/dosextens.i
include utility/tagitem.i
incdir dh1:t/ass/Include/
include libraries/CrM.i
include libraries/CrM_lib.i
*************************************************
CALL MACRO
jsr _LVO\1(a6)
ENDM
CALLEXEC MACRO
move.l 4.w,a6
CALL \1
ENDM
CALLCRM MACRO
move.l _CrMBase(pc),a6
CALL \1
ENDM
CALLDOS MACRO
move.l _DOSBase(pc),a6
CALL \1
ENDM
*************************************************
CrunchOnly equ 1
DecrunchOnly equ 2
ExtraMemLen equ 100
*************************************************
main:
lea CommandLine(pc),a1
movem.l d0/a0,(a1) ;save CLI-Parameters
** Open dos.library: **
lea DOSName(pc),a1
CALLEXEC OldOpenLibrary
lea _DOSBase(pc),a0
move.l d0,(a0)
beq.s .End
** Get output handle: **
move.l d0,a6
CALL Output
lea OutHandle(pc),a0
move.l d0,(a0)
beq.s .CloseDOS
** Open CrM.library: **
lea CrMName(pc),a1
moveq #4,d0
CALLEXEC OpenLibrary
lea _CrMBase(pc),a0
move.l d0,(a0)
beq.s .CloseDOS
** Do all actions: **
bsr.s mainloop
** Close CrM.library: **
move.l _CrMBase(pc),a1
CALLEXEC CloseLibrary
** Close dos.library: **
.CloseDOS:
move.l _DOSBase(pc),a1
CALLEXEC CloseLibrary
** Return to the CLI: **
.End: moveq #0,d0
rts
*----------
mainloop:
lea InitTxt(pc),a0
bsr.w PrintText
** Analyse Commandline: **
movem.l CommandLine(pc),d1/a1 ;get Parameters
clr.b -1(a1,d1.w) ;replace <cr> by Null
move.b (a1),d0
beq.w .usage ;no Parameters
cmp.b #"?",d0
beq.w .usage ;question mark -> print usage
lea Algorithm(pc),a2
move.w (a2),d1 ;default Algorithm
cmp.b #"-",d0
bne.w .noopts ;no option specified
addq.l #1,a1
** Optionsloop: processes all options, no spaces between options are allowed!
.optsloop:
move.b (a1)+,d0 ;get char
beq.w .usage
cmp.b #" ",d0
beq.w .noopts ;no more options
cmp.b #"1",d0
beq.s .norm
cmp.b #"2",d0
beq.s .lzh
cmp.b #"c",d0
beq.s .crunch
cmp.b #"d",d0
beq.s .decrunch
cmp.b #"f",d0
beq.s .flash
cmp.b #"l",d0
beq.s .longer
cmp.b #"s",d0
beq.s .sample
cmp.b #"y",d0
beq.s .encrypt
lea UnknownOpt(pc),a0
move.b d0,(a0)
lea UnknownOptTxt(pc),a0
bsr.w PrintText
bra.s .optsloop
*-----
.norm: and.w #$fff0,d1 ;kill old algorithm
or.w #cm_Normal,d1 ;new algo
bra.s .optsloop
*-----
.lzh: and.w #$fff0,d1 ;kill old algorithm
or.w #cm_LZH,d1 ;new algo
bra.s .optsloop
*-----
.crunch:
lea Operation(pc),a0
move.b #CrunchOnly,(a0)
bra.s .optsloop
*-----
.decrunch:
lea Operation(pc),a0
move.b #DecrunchOnly,(a0)
bra.s .optsloop
*-----
.flash:
bset #cmB_LEDFlash,d1
bra.s .optsloop
*-----
.longer:
lea LongerFileFlag(pc),a0
st (a0)
bra.w .optsloop
*-----
.sample:
bset #cmB_Sample,d1
bra.w .optsloop
*-----
.encrypt:
bset #cmB_PW,d1
bra.w .optsloop
*-----
.noopts:
move.w d1,(a2) ;algorithm
lea SourceName(pc),a0
move.l a1,(a0)
lea DestName(pc),a0 ;normally Source- and DestName are
move.l a1,(a0) ;the same...
.search:
move.b (a1)+,d0
beq.s .samedest ;no second filename
cmp.b #" ",d0
bne.s .search
move.l a1,(a0) ;new DestName
clr.b -1(a1) ;replace <Space> by Null
.samedest:
** Open Sourcefile: **
move.l SourceName(pc),d1
move.l #MODE_OLDFILE,d2
CALLDOS Open
move.l d0,d5
beq.w .srcnotopen
** Read DataHeader (first 14 Bytes in the file): **
move.l d5,d1
lea DataHdr(pc),a0
move.l a0,d2
moveq #14,d3
CALL Read
lea DataHdr(pc),a0
CALLCRM cmCheckCrunched
lea Operation(pc),a0
tst.l d0
beq.s .loadnormal ;file is not crunched with CrM
cmp.b #CrunchOnly,(a0)
beq.w .alreadycrunched ;can't crunch twice!
move.b #DecrunchOnly,(a0)
bsr.w CrunchedLoad ;load crunched file
bra.s .crloadcont
.loadnormal:
cmp.b #DecrunchOnly,(a0)
beq.w .notcrunched
move.b #CrunchOnly,(a0)
bsr.w NormalLoad ;load original file
.crloadcont:
move.l d0,-(sp) ;save return code
move.l d5,d1
CALLDOS Close ;close Sourcefile
move.l (sp)+,d0
beq.s .done ;loading failed!
move.b Operation(pc),d0
cmp.b #DecrunchOnly,d0
bne.s .nodecr
bsr.w DecrunchIt ;decrunch data
beq.s .done
.nodecr:
move.b Operation(pc),d0
cmp.b #DecrunchOnly,d0
bne.s .nodecrsave
bsr.w DecrunchedSave ;save original data
.nodecrsave:
move.b Operation(pc),d0
cmp.b #CrunchOnly,d0
bne.s .nocr
bsr.w CrunchIt ;crunch data
beq.s .done
.nocr:
move.b Operation(pc),d0
cmp.b #CrunchOnly,d0
bne.s .nocrsave
bsr.w CrunchedSave ;save crunched data
.nocrsave:
.done:
** Free cmCrunchStruct: **
move.l CrStruct(pc),d0
beq.s .nocrstruct ;no cmCrunchStruct allocated
move.l d0,a1
moveq #cm_FreeStruct,d0
CALLCRM cmProcessCrunchStructA
.nocrstruct:
** Free Buffer: **
move.l MemBase(pc),a1
move.l MemLen(pc),d0
beq.s .End
CALLEXEC FreeMem
.End: rts
*-------
** Sourcefile open failed! **
.srcnotopen:
move.l SourceName(pc),a0
move.l a0,-(sp)
lea NotOpenTxt(pc),a0
move.l sp,a1
bsr.s RawPrintText
addq.l #4,sp
rts
*-------
** DecrunchOnly: File is not crunched **
.notcrunched:
lea NotCrunchedTxt(pc),a0
.acrcont:
move.l SourceName(pc),-(sp)
move.l sp,a1
bsr.s RawPrintText
addq.l #4,sp
moveq #0,d0
bra.w .crloadcont
*-----
** CrunchOnly: File is already crunched **
.alreadycrunched:
lea AlreadyCrTxt(pc),a0
bra.s .acrcont
*-------
** Print Usage: **
.usage: lea UsageTxt(pc),a0
; bra.s PrintText
********************************
** Print some text to the CLI **
PrintText: ** a0:Text
movem.l d0-d3/a0-a1/a6,-(sp)
move.l a0,d2
move.l OutHandle(pc),d1
moveq #-1,d3
.count: addq.l #1,d3
tst.b (a0)+
bne.s .count
CALLDOS Write
movem.l (sp)+,d0-d3/a0-a1/a6
rts
*----------
** Print some text to the CLI with formatting using RawDoFmt(): **
RawPrintText: ** a0:Text a1:Args
movem.l d0-d2/a0-a3/a6,-(sp)
lea .stuffchar(pc),a2
lea InitTxt(pc),a3
CALLEXEC RawDoFmt
lea InitTxt(pc),a0
bsr.s PrintText ;print the converted text
movem.l (sp)+,d0-d2/a0-a3/a6
rts
*-----
.stuffchar:
move.b d0,(a3)+ ;put data to output string
rts
*****************************
** Load a file to crunch it. A cmCrunchStruct and the Buffer for the file
** will be allocated.
NormalLoad:
** Get Lock on the Sourcefile: **
move.l SourceName(pc),d1
moveq #ACCESS_READ,d2
CALLDOS Lock
move.l d0,d4
beq.w .notopen ;locking failed!
** Examine Sourcefile: **
move.l d4,d1
lea InitTxt(pc),a0 ;InitTxt serves as buffer for the fib
move.l a0,d2
CALL Examine
move.l d0,-(sp) ;save result on the stack
** UnLock Sourcefile: **
move.l d4,d1
CALL UnLock
move.l (sp)+,d0
beq.w .notopen ;examining failed!
lea InitTxt(pc),a0
move.l fib_Size(a0),d7 ;Size of Sourcefile
** Allocate Buffer (Len=Sourcefilelength+ExtraMemLen): **
moveq #ExtraMemLen,d0
add.l d7,d0
lea MemLen(pc),a0
move.l d0,(a0)
moveq #0,d1
CALLEXEC AllocMem
lea MemBase(pc),a0
move.l d0,(a0)
beq.w .nomem ;not enough memory
** Allocate a cmCrunchStruct: **
clr.l -(sp) ;TAG_DONE
move.w Algorithm(pc),-(sp)
clr.w -(sp)
move.l #CMCS_Algo,-(sp)
move.l sp,a0
moveq #cm_AllocStruct,d0
CALLCRM cmProcessCrunchStructA
lea 12(sp),sp
lea CrStruct(pc),a0
move.l d0,(a0)
beq.s .nomem ;allocating failed
move.l d7,-(sp)
move.l SourceName(pc),a0
move.l a0,-(sp)
lea LoadingTxt(pc),a0
move.l sp,a1
bsr.w RawPrintText
addq.l #8,sp
** Copy DataHeader to Buffer **
move.l MemBase(pc),a1
add.w #ExtraMemLen,a1
lea DataHdr(pc),a0
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.w (a0)+,(a1)+
** Load rest of sourcefile **
move.l d5,d1
move.l a1,d2
move.l d7,d3
subq.l #8,d3
subq.l #6,d3
CALLDOS Read
cmp.l d0,d3
bne.s .readerr ;readerror
lea OrigLen(pc),a0
move.l d7,(a0) ;Originallen (Length of Sourcefile)
lea ReturnTxt(pc),a0
bsr.w PrintText
moveq #1,d0 ;return: TRUE
rts
*-----
** Opening failed: **
.notopen:
move.l SourceName(pc),a0
move.l a0,-(sp)
lea NotOpenTxt(pc),a0
move.l sp,a1
bsr.w RawPrintText
addq.l #4,sp
.Exit: moveq #0,d0 ;return: FALSE
rts
*-----
** not enough memory available: **
.nomem: lea MemLen(pc),a0
clr.l (a0)
lea NoMemTxt(pc),a0
.prtx: bsr.w PrintText
bra.s .Exit
** readerror: **
.readerr:
lea ReadErrTxt(pc),a0
bra.s .prtx
*------------
** Crunch Data: **
CrunchIt:
lea CrunchingTxt(pc),a0
bsr.w PrintText
move.l CrStruct(pc),a0
move.l MemBase(pc),a1
move.l a1,cmcr_Dest(a0)
moveq #ExtraMemLen,d0
add.l d0,a1
move.l a1,cmcr_Src(a0)
move.l OrigLen(pc),d1
move.l d1,cmcr_SrcLen(a0)
add.l d0,d1
move.l d1,cmcr_DestLen(a0)
lea DataHdr(pc),a1
move.l a1,cmcr_DataHdr(a0)
clr.l cmcr_DisplayHook(a0)
move.w #$7ffe,cmcr_DisplayStep(a0)
CALLCRM cmCrunchData
lea CrLen(pc),a0
move.l d0,(a0)
beq.s .error ;error while crunching
** calculate gain in percent: you have to do this complicated rotating
** because there is no longword division available on a standard 68000
** this routine is not very cool, it will produce shit when the gain is
** negative. (Problem now fixed).
move.l OrigLen(pc),d1
move.l d1,d2
move.l d1,d3
moveq #0,d4
sub.l d0,d2 ;gain
bpl.s .rotloop
neg.l d2
moveq #1,d4
.rotloop:
tst.l d2
bmi.s .rotend
tst.l d3
bmi.s .rotend
add.l d2,d2
add.l d3,d3
bra.s .rotloop
.rotend:
lsr.l #1,d2
lsr.l #1,d3
clr.w d2
clr.w d3
swap d2
swap d3
mulu #100,d2
divu d3,d2
tst.w d4
beq.s .noneg
neg.w d2
.noneg: move.w d2,-(sp)
move.l d0,-(sp)
move.l d1,-(sp)
move.l sp,a1
lea CrunchedTxt(pc),a0
bsr.w RawPrintText
lea 10(sp),sp
moveq #1,d0 ;return: TRUE
rts
** error while crunchung: **
.error: move.l CrStruct(pc),a0
move.b cmcr_QuitFlag(a0),d0
lea AbortTxt(pc),a0
cmp.b #"a",d0
beq.s .errend ;crunching was aborted (not possible yet)
lea NotCrTxt(pc),a0
cmp.b #"n",d0
beq.s .errend ;data is not crunchable (or already
;crunched with another packer)
lea UnknownErrTxt(pc),a0
.errend:
bsr.w PrintText
moveq #0,d0 ;return: FALSE
rts
*----------
** Save crunched data: **
CrunchedSave:
** Open Destination file: **
move.l OrigLen(pc),d0
sub.l CrLen(pc),d0
subq.l #8,d0
subq.l #6,d0
bgt.s .cont
move.b LongerFileFlag(pc),d0
bne.s .cont ;keep longer files
lea TooLongFileTxt(pc),a0
bra.w RawPrintText
*-----
.cont: move.l DestName(pc),d1
move.l #MODE_NEWFILE,d2
CALLDOS Open
move.l d0,d5
beq.s .notopen ;open failed
moveq #14,d0
add.l CrLen(pc),d0
move.l d0,-(sp)
move.l DestName(pc),-(sp)
move.l sp,a1
lea SavingTxt(pc),a0
bsr.w RawPrintText
addq.l #8,sp
** Write DataHeader: **
move.l d5,d1
lea DataHdr(pc),a0
move.l a0,d2
moveq #14,d3
CALL Write ;DataHeader
tst.l d0
bmi.s .error ;writeerror
** Write crunched Data: **
move.l d5,d1
move.l MemBase(pc),d2
move.l CrLen(pc),d3
CALL Write ;Data
tst.l d0
bmi.s .error ;writeerror
** Close Destination file: **
move.l d5,d1
CALL Close
** Generate Comment: **
lea Comment(pc),a0
move.l OrigLen(pc),-(sp)
move.l sp,a1
lea .stuffchar(pc),a2
lea InitTxt(pc),a3 ;again InitTxt serves as a temporary
;buffer
CALLEXEC RawDoFmt
addq.l #4,sp
** Set Comment (for RTDD): **
move.l DestName(pc),d1
lea InitTxt(pc),a0
move.l a0,d2
CALLDOS SetComment
lea ReturnTxt(pc),a0
bra.w PrintText ;print texte and return (no returncode)
*-----
** Destfile open failed: **
.notopen:
move.l DestName(pc),-(sp)
move.l sp,a1
lea NotOpenTxt(pc),a0
bsr.w RawPrintText
addq.l #4,sp
rts
*-----
** writeerror: **
.error: lea ErrorWriteTxt(pc),a0
bsr.w PrintText
** close destfile: **
move.l d5,d1
CALL Close
** delete destfile: **
move.l DestName(pc),d1
CALL DeleteFile
rts
*-----
.stuffchar:
move.b d0,(a3)+ ;put data to output string
rts
*****************************
** Load data to decrunch (Buffer will be allocated): **
CrunchedLoad:
** Copy contents of DataHeader to internal Variables: **
lea DataHdr(pc),a0
lea OrigLen(pc),a1
move.l dh_OriginalLen(a0),(a1)
lea CrLen(pc),a1
move.l dh_CrunchedLen(a0),(a1)
** Allocate Buffer (len=OrigLen+MinSecDist): **
moveq #0,d0
move.w dh_MinSecDist(a0),d0
add.l dh_OriginalLen(a0),d0
lea MemLen(pc),a0
move.l d0,(a0)
moveq #0,d1
CALLEXEC AllocMem
lea MemBase(pc),a0
move.l d0,(a0)
beq.w .nomem ;not enough memory
moveq #14,d0
add.l CrLen(pc),d0
move.l d0,-(sp)
move.l SourceName(pc),-(sp)
move.l sp,a1
lea LoadingTxt(pc),a0
bsr.w RawPrintText
addq.l #8,sp
** Read crunched Data: **
move.l d5,d1
move.l MemBase(pc),d2
move.l CrLen(pc),d3
CALLDOS Read
cmp.l d0,d3
bne.s .readerr ;readerror
moveq #1,d0 ;return: TRUE
lea ReturnTxt(pc),a0
bra.s .prtx
*-----
.readerr:
moveq #0,d0 ;return: FALSE
lea ReadErrTxt(pc),a0
bra.s .prtx
*-----
.nomem: lea MemLen(pc),a0
clr.l (a0)
moveq #0,d0 ;return: FALSE
lea NoMemTxt(pc),a0
.prtx: bra.w PrintText
*------------
** Decrunch Data: **
DecrunchIt:
move.l OrigLen(pc),-(sp)
move.l CrLen(pc),-(sp)
move.l sp,a1
lea DecrunchingTxt(pc),a0
bsr.w RawPrintText
addq.l #8,sp
lea DataHdr(pc),a2
move.l MemBase(pc),a0
move.w dh_MinSecDist(a2),d0
lea 0(a0,d0.w),a1
CALLCRM cmDecrunch
tst.l d0
beq.s .error
lea ReturnTxt(pc),a0
bsr.w PrintText
moveq #1,d0 ;return: TRUE
rts
*-----
** error while decrunching: **
.error:
lea DecrErrorTxt(pc),a0
bsr.w PrintText
moveq #0,d0 ;return: FALSE
rts
*----------
** Save original (decrunched) file: **
DecrunchedSave:
** Open Destination file: **
move.l DestName(pc),d1
move.l #MODE_NEWFILE,d2
CALLDOS Open
move.l d0,d5
beq.s .notopen ;openfail
move.l OrigLen(pc),-(sp)
move.l DestName(pc),-(sp)
move.l sp,a1
lea SavingTxt(pc),a0
bsr.w RawPrintText
addq.l #8,sp
** Write Data: **
move.l d5,d1
lea DataHdr(pc),a0
moveq #0,d2
move.w dh_MinSecDist(a0),d2
add.l MemBase(pc),d2
move.l OrigLen(pc),d3
CALL Write ;Data
tst.l d0
bmi.s .error ;writeerror
** Close File: **
move.l d5,d1
CALL Close
lea ReturnTxt(pc),a0
bra.w PrintText ;print text and return (no returncode)
*-----
** destfile could not be opened: **
.notopen:
move.l DestName(pc),-(sp)
move.l sp,a1
lea NotOpenTxt(pc),a0
bsr.w RawPrintText
addq.l #4,sp
rts
*-----
** writeerror: **
.error: lea ErrorWriteTxt(pc),a0
bsr.w PrintText
** Close destfile: **
move.l d5,d1
CALL Close
** Delete destfile: **
move.l DestName(pc),d1
CALL DeleteFile
rts
*************************************************
_DOSBase: dc.l 0
_CrMBase: dc.l 0
OutHandle: dc.l 0 ;Handle to print text in the CLI
MemBase: dc.l 0 ;Start of Buffer
MemLen: dc.l 0 ;Length of Buffer
OrigLen: dc.l 0 ;Original Length of Data
CrLen: dc.l 0 ;Crunched Length if Data
CrStruct: dc.l 0 ;struct cmCrunchStruct *
CommandLine: dc.l 0,0 ;CLI-Parameters (text *, len)
SourceName: dc.l 0 ;Sourcefilename *
DestName: dc.l 0 ;Destinationfilename *
DataHdr: ds.b 14 ;struct DataHeader
Algorithm: dc.w cm_LZH!cmF_Overlay ;Algorithm for cmcs_Algo Tag
Operation: dc.b 0 ;type of Operation (CrunchOnly,
;DecrunchOnly or NULL for auto)
LongerFileFlag: dc.b 0 ;keep longer files?
DOSName: dc.b "dos.library",0
CrMName: CRMNAME
cnop 0,4
InitTxt: dc.b 27,"[33;1mCrMData ",27,"[0;33mV1.01 ",27,"[0m--- "
dc.b 27,"[32m(c) 1993 Thomas Schwarz",27,"[0m",10,10,0
dc.b "$VER: CrMData 1.01",0
UsageTxt: dc.b "Usage: CrMData [-12cdfsy] <sourcefile> [<destfile>]",10
dc.b "-1 : use CrM-Normal algorithm",10
dc.b "-2 : use LZ-Huffman algorithm",10
dc.b "-c : crunch only",10
dc.b "-d : decrunch only",10
dc.b "-f : enable Power-LED flashing",10
dc.b "-l : save file, even if it becomes longer",10
dc.b "-s : use Sample-Mode",10
dc.b "-y : enable password encryption",10,0
UnknownOptTxt: dc.b "Unknown option: -"
UnknownOpt: dc.b " !"
ReturnTxt: dc.b 10,0
NotOpenTxt: dc.b "Could not open `%s'!",10,0
LoadingTxt: dc.b "Loading `%s' (%ld bytes)...",0
NoMemTxt: dc.b "Not enough memory available!",10,0
ReadErrTxt: dc.b "Read Error!",10,0
NotCrunchedTxt: dc.b "Can't decrunch `%s': File is not crunched!",10,0
AlreadyCrTxt: dc.b "Can't crunch `%s': File is already crunched!",10,0
CrunchingTxt: dc.b "Crunching...",0
CrunchedTxt: dc.b " %ld -> %ld (%d%% gain)",10,0
AbortTxt: dc.b "Crunching aborted!",10,0
NotCrTxt: dc.b "File not crunchable!",10,0
UnknownErrTxt: dc.b "Strange error occurred while crunching!",10,0
SavingTxt: dc.b "Saving `%s' (%ld bytes)...",0
ErrorWriteTxt: dc.b " Error while writing!",10,0
Comment: dc.b "CrM!%08lx",0
DecrunchingTxt: dc.b "Decrunching (%ld -> %ld)...",0
DecrErrorTxt: dc.b " Error while decrunching!",10,0
TooLongFileTxt: dc.b "File not saved: crunched file is longer than original",10,0